home *** CD-ROM | disk | FTP | other *** search
Lex Description | 1994-04-01 | 7.0 KB | 230 lines |
- %{
- {* Assembler parsing for Mangler, see MANGLER.L
- Copyright (C) 1993 Berend de Boer
-
- This program is free software for noncommercial users; you can
- redistribute it and/or modify it under the terms of the license,
- stated in de accompanying file LICENSE.TXT.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- license for more details.
-
- See the accompanying READ.ME file for information on contacting the
- author.
-
-
- $Author: Berend_de_Boer $
- $Date: 93/04/29 07:52:25 $
- $Revision: 1.2 $
-
- Last changes:
- 93-04-19 Fixed the & identifier override bug
- *}
-
- procedure ParseAsm;
-
- %}
-
- NQUOTE [^']
- DQUOTE [^'}]
-
- %%
-
- %{
- function is_keyword(const id : string) : Boolean;
- {**}
- const
- id_len = 6;
- type
- Ident = string[id_len];
- const
- (* table of assembler keywords: *)
- no_of_keywords = 192;
- keyword : array [1..no_of_keywords] of Ident = (
- 'AAA', 'AAD', 'AAM', 'AAS', 'ADC', 'ADD', 'AH', 'AL', 'AND', 'AND',
- 'AX', 'BH', 'BL', 'BOUND', 'BP', 'BX', 'BYTE', 'CALL', 'CBW', 'CH',
- 'CL', 'CLC', 'CLD', 'CLI', 'CMC', 'CMP', 'CMPS', 'CMPSB', 'CMPSD',
- 'CMPSW', 'CS', 'CX', 'DAA', 'DAS', 'DEC', 'DH', 'DI', 'DIV', 'DL', 'DS',
- 'DWORD', 'DX', 'ENTER', 'ES', 'FAR', 'HIGH', 'HLT', 'IDIV', 'IMUL',
- 'IN', 'INC', 'INS', 'INSB', 'INSD', 'INSW', 'INT', 'INTO', 'IRET', 'JA',
- 'JAE', 'JB', 'JBE', 'JC', 'JCXZ', 'JE', 'JG', 'JGE', 'JL', 'JLE', 'JMP',
- 'JNA', 'JNAE', 'JNB', 'JNBE', 'JNC', 'JNE', 'JNG', 'JNGE', 'JNL',
- 'JNLE', 'JNO', 'JNP', 'JNS', 'JNZ', 'JO', 'JP', 'JPE', 'JPO', 'JS',
- 'JZ', 'JZ', 'LAHF', 'LAR', 'LDS', 'LEA', 'LEAVE', 'LES', 'LGDT', 'LIDT',
- 'LLDT', 'LMSW', 'LOCK', 'LODS', 'LODSB', 'LODSW', 'LOOP', 'LOOPE',
- 'LOOPNE', 'LOOPNZ', 'LOOPZ', 'LOW', 'LSL', 'LTR', 'MOD', 'MOV', 'MOVS',
- 'MOVSB', 'MOVSW', 'MUL', 'NEAR', 'NEG', 'NOP', 'NOT', 'NOT', 'OFFSET',
- 'OR', 'OR', 'OUT', 'OUTS', 'OUTSB', 'OUTSW', 'POP', 'POPA', 'POPF',
- 'PTR', 'PUSH', 'PUSHA', 'PUSHF', 'QWORD', 'RCL', 'RCR', 'REP', 'REPE',
- 'REPNE', 'REPNZ', 'REPZ', 'RET', 'ROL', 'ROR', 'SAHF', 'SAL', 'SAR',
- 'SBB', 'SCAS', 'SCASB', 'SCASW', 'SEG', 'SEGDS', 'SEGES', 'SEGSS', 'SGDT', 'SHL', 'SHL', 'SHR',
- 'SHR', 'SI', 'SIDT', 'SLDT', 'SMSW', 'SP', 'SS', 'ST', 'STC', 'STD',
- 'STI', 'STOS', 'STOSB', 'STOSW', 'STR', 'SUB', 'TBYTE', 'TEST', 'TYPE',
- 'VERR', 'VERW', 'WAIT', 'WORD', 'XCHG', 'XLAT', 'XLATB', 'XOR', 'XOR');
- var m, n, k : integer;
- begin
- m := 1; n := no_of_keywords;
- while m<=n do begin
- k := m+(n-m) div 2;
- if id=keyword[k]
- then begin
- is_keyword := true;
- Exit;
- end
- else if id>keyword[k]
- then m := k+1
- else n := k-1
- end; { of while }
- is_keyword := false
- end;
-
- var
- Stop : Boolean;
- %}
-
-
-
-
- [A-Za-z]([a-zA-Z])* begin
- yytext := UpStr(yytext);
- if is_keyword(yytext)
- then return(KEYWORD)
- else begin
- if yytext = 'END'
- then return(_END)
- else return(IDENTIFIER);
- end;
- end;
-
- [a-zA-Z_]([a-zA-Z0-9_])* begin
- yytext := UpStr(yytext);
- return(IDENTIFIER);
- end;
-
- "&" return(AMPERSAND);
-
- [@]+([a-zA-Z0-9_])+ return(_LABEL);
-
- ";" return(SEMICOLON);
- "." return(DOT);
-
- '({NQUOTE}|'')*' return(CHARACTER_STRING);
-
- [0-9]([0-9-a-fA-F])*[hH] |
- [$]([0-9a-fA-F])+ |
- [0-9]+ return(NUMBER);
-
- "{$"({DQUOTE})*"}" return(DIRECTIVE);
-
- "(*" begin
- Stop := FALSE;
- repeat
- if (get_char = '*') and (get_char = ')') then
- Stop := TRUE;
- until Stop;
- end;
-
- "{" begin
- repeat
- until get_char = '}';
- end;
-
- [ \t\f] ;
-
- \n begin
- if Random(50) = 25 then
- WriteProgress;
- return(NEWLINE);
- end;
-
- . return(OTHER);
-
- %%
- (**)
-
- function GiveEncodingFor(s : string) : string;
- {* DO NOT MAKE s a const string!!! *}
- { PRE -
- POST - contents of yytext is destroyed
- }
- var
- p : PScopeCol;
- e : string;
- Index : integer;
- begin
- if yylex = DOT
- then begin
- {* a dot was used to select a different scope *}
- p := GetScope(s, Index);
- if p = nil
- then begin {* an unknown scope was selected *}
- e := s + '.';
- while (yylex = IDENTIFIER) do begin
- e := e + yytext;
- if yylex = DOT
- then e := e + '.'
- else Break;
- end;
- yyless(0);
- end
- else begin
- PushScope(CurrentScope);
- CurrentScope := p^.AtScope(Index);
- e := p^.AtHashedName(Index) + '.';
- while (yylex = IDENTIFIER) do begin
- if CurrentScope = nil
- then e := e + yytext
- else begin
- CurrentScope^.Search(@yytext, Index);
- e := e + CurrentScope^.AtHashedName(Index);
- end;
- if yylex = DOT
- then begin
- if CurrentScope <> nil then
- CurrentScope := CurrentScope^.AtScope(Index);
- e := e + '.';
- end
- else Break;
- end; { of while }
- yyless(0);
- CurrentScope := PopScope;
- end;
- GiveEncodingFor := e;
- end
- else begin
- yyless(0);
- p := GetScope(s, Index);
- if p = nil
- then GiveEncodingFor := s
- else GiveEncodingFor := p^.AtHashedName(Index)
- end;
- end;
-
- begin
- write(yyoutput, yytext, ' ');
- while yylex <> _END do begin
- case yyretval of
- IDENTIFIER : write(yyoutput, GiveEncodingFor(yytext));
- NEWLINE : writeln(yyoutput, '{}');
- AMPERSAND : begin
- write(yyoutput, yytext);
- yylex;
- write(yyoutput, GiveEncodingFor(yytext));
- end;
- else write(yyoutput, yytext, ' ');
- end; { of case }
- end; { of while }
- writeln(yyoutput);
- write(yyoutput, yytext);
- if AssemblerSection then begin
- Section := PopSection;
- CurrentScope := PopScope;
- if ObjectImpl then begin
- CurrentScope := PopScope;
- ObjectImpl := FALSE;
- end;
- AssemblerSection := FALSE;
- end;
- end;